#import "AllinDESEDEUtil.h"
#import <CommonCrypto/CommonCryptor.h>

@implementation AllinDESEDEUtil

+ (NSData *)DESEDEEncryptedDataWithKey:(NSString *)key data:(NSData*)data
{
    return [self DESEDEEncryptedDataWithKey:key data:data iv:nil];
}

+ (NSData *)DESEDEDecryptedDataWithKey:(NSString *)key data:(NSData*)data
{
    return [self DESEDEDecryptedDataWithKey:key data:data iv:nil];
}

+ (NSData *)DESEDEEncryptedDataWithKey:(NSString *)key data:(NSData*)data  iv:(NSString *)iv
{
    return [self DESEDEOperation:kCCEncrypt key:key data:data iv:iv];
}

+ (NSData *)DESEDEDecryptedDataWithKey:(NSString *)key data:(NSData*)data  iv:(NSString *)iv
{
    return [self DESEDEOperation:kCCDecrypt key:key data:data iv:iv];
}

+ (NSData *)DESEDEOperation:(CCOperation)operation key:(NSString *)key data:(NSData*)data  iv:(NSString *)iv
{
    char keyPtr[kCCKeySize3DES + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    char ivPtr[kCCKeySize3DES + 1];
    bzero(ivPtr, sizeof(ivPtr));
    if (iv) {
        [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
    }
    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCKeySize3DES;
    void *buffer = malloc(bufferSize);
    
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(operation,
                                          kCCAlgorithm3DES,
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          keyPtr,
                                          kCCKeySize3DES,
                                          ivPtr,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    free(buffer);
    return nil;
}
@end
